package com.gitee.cirnochat.common.config;

import com.gitee.cirnochat.websocket.interceptor.MyChannelInterceptor;
import com.gitee.cirnochat.websocket.interceptor.MyHandshakeInterceptor;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.ChannelRegistration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;


/**
 * WebSocket 配置类
 * 主要用于开启 WebSocket/STOMP 支持，注册连接点和消息代理。
 *
 * @author FlanChan
 * @date 2025/4/168- 12:46
 */
@Configuration
@EnableWebSocketMessageBroker // 启用基于代理的 WebSocket 消息处理
@RequiredArgsConstructor
@Data
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    private final MyHandshakeInterceptor handshakeInterceptor;

    private final MyChannelInterceptor channelInterceptor;
    /**
     * WebSocket 节点 ID 用于分布式websocket集群
     */
    @Value("${websocket.node-id:node-1}")
    private String nodeId;

    /**
     * 注册 STOMP 连接端点（供客户端连接）
     *
     * @param registry 端点注册器
     */
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        // 客户端连接的端点路径：/ws
        // setAllowedOrigins("*") 允许所有来源访问（可根据需要限制）
        // withSockJS() 表示支持 SockJS 回退方案（兼容不支持 WebSocket 的浏览器）
        registry.addEndpoint("/ws")
                .addInterceptors(handshakeInterceptor) // 添加握手拦截器
                .setAllowedOriginPatterns("*");
    }

    /**
     * 配置消息代理（处理消息的路由）
     *
     * @param registry 消息代理注册器
     */
    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        // 启用简单内存消息代理，前缀为 /topic 和 /webrtc 的消息会被广播到订阅者
        registry.enableSimpleBroker("/chat", "/webrtc", "/system");

        // 客户端发送消息时应用前缀，例如发送到 @MessageMapping("/chat") 映射的方法
        registry.setApplicationDestinationPrefixes("/app"); // 如果客户端发送消息到 /app/chat，则会被路由到 @MessageMapping("/chat") 的方法

        // 点对点发送的用户前缀（例如发送给某个用户的消息会使用 /user/开头）
        registry.setUserDestinationPrefix("/user");
    }



    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.interceptors(channelInterceptor);
    }
}
